package com.edu.robot.modules.robot.controller;


import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.edu.buservice.util.model.TenantUtil;
import com.edu.chat.facade.model.dto.SendMessageDTO;
import com.edu.chat.facade.model.enums.MsgTypeEnum;
import com.edu.robot.common.constants.IMConstant;
import com.edu.robot.common.service.RedisUtil;
import com.edu.robot.core.enums.NotifyMsgEnum;
import com.edu.robot.core.model.APICallback;
import com.edu.robot.core.model.QueryContext;
import com.edu.robot.core.service.RobotService;
import com.edu.robot.model.R;
import com.edu.robot.model.enums.ResultCodeEnum;
import com.edu.robot.model.error.BizException;
import com.edu.robot.modules.robot.controller.vo.PageQuery;
import com.edu.robot.modules.robot.controller.vo.QueryRobotVO;
import com.edu.robot.modules.robot.controller.vo.RobotVO;
import com.edu.robot.modules.robot.dto.RobotInfoDTO;
import com.edu.robot.modules.robot.service.CrRobotService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.concurrent.CompletableFuture;

/**
 * @program: KQAIA
 * @description:
 * @author: 无恙
 * @create: 2025-03-23 11:19
 **/

@RestController
@RequestMapping("/robot/config")
@Slf4j
public class RobotController {

	@Autowired
	private CrRobotService crRobotService;

	@Autowired
	private RobotService robotService;

	@Autowired
	private RedisUtil redisUtil;

	@PostMapping("/add")
	public R<?> addRobot(@RequestBody @Validated RobotVO robotVO) {
		return crRobotService.createRobot(robotVO);
	}

	//分页获取机器人信息
	@PostMapping("/list")
	public R<?> listRobot(@RequestBody PageQuery<QueryRobotVO> robotVO) {
		return R.success(crRobotService.queryRobotList(robotVO));
	}

	//更新机器人信息
	@PostMapping("/update")
	public R<?> updateRobot(@RequestBody @Validated RobotVO robotVO) {
		return crRobotService.updateRobot(robotVO);
	}

	@DeleteMapping("/delete/{id}")
	public R<?> deleteRobot(@PathVariable("id") String id) {
		return R.success(crRobotService.removeById(id));
	}

	@RequestMapping(value = "/chat/event", produces = "text/event-stream")
	@CrossOrigin
	public SseEmitter createSse(String content,String robotId, Boolean openSearch) {

		log.info("RobotController createSse content:{},openSearch:{}",content,openSearch);
		if(StringUtils.isAllBlank(content,robotId)){
			throw new BizException(ResultCodeEnum.PARAM_INVALID,"参数不能为空");
		}

		//默认30秒超时,设置为0L则永不超时
		SseEmitter sseEmitter = new SseEmitter(0L);
		//完成后回调
		try {
			sseEmitter.send(SseEmitter.event().reconnectTime(5000));
		} catch (IOException e) {
			throw new BizException(ResultCodeEnum.IM_SESSION_CREATE_ERROR);
		}


		String uid = StpUtil.getLoginIdAsString();

		String tenantId = TenantUtil.getTenantId();

		CompletableFuture.runAsync(() -> {

			try {
				QueryContext queryContext = new QueryContext();
				queryContext.setUserInput(content);
				queryContext.setRobotId(robotId);
				queryContext.setSearchEnable(openSearch);
				queryContext.setTenantId(tenantId);
				queryContext.setSessionId("0");
				queryContext.setUserId(uid);

				final String robotKey= IMConstant.ROBOT_CONFIG_REDIS_KEY+robotId;

				RobotInfoDTO robotInfoDTO = redisUtil.get(robotKey, RobotInfoDTO.class);

				if(robotInfoDTO == null){
					//从数据库中获取机器人信息
					R<RobotInfoDTO> robot = crRobotService.getRobot(Long.valueOf(robotId));
					if(!robot.isSuccess() || robot.getData() == null){
						throw new BizException(ResultCodeEnum.DATABASE_ERROR,"机器人配置信息不存在");
					}
					robotInfoDTO = robot.getData();
					//设置机器人信息到redis中
					redisUtil.set(robotKey,robotInfoDTO,60*5);
				}

				queryContext.setRobotInfoDTO(robotInfoDTO);
				queryContext.setApiCallback(new APICallback() {
					final String messageId = IdUtil.getSnowflakeNextIdStr();
					@Override
					public void onEvent(NotifyMsgEnum notification,String msg) {

						SendMessageDTO sentMessageDTO = new SendMessageDTO();
						sentMessageDTO.setUserId(uid);
						sentMessageDTO.setRobotId(robotId);
						sentMessageDTO.setTenantId(tenantId);
						sentMessageDTO.setMsgType(MsgTypeEnum.ROBOT.getCode());
						sentMessageDTO.setMessageId(messageId);
						sentMessageDTO.setContent(msg);
						String jsonStr = JSONUtil.toJsonStr(sentMessageDTO);
						try {
							sseEmitter.send(SseEmitter.event().id(messageId).reconnectTime(1*60*1000L).data(jsonStr));
						} catch (IOException e) {
							log.error("RobotController createSse error:{}",e.getMessage());
							throw new BizException(ResultCodeEnum.IM_SESSION_CREATE_ERROR);
						}

					}

					@Override
					public void close(String finalMsg) {

						SendMessageDTO sentMessage = new SendMessageDTO();
						sentMessage.setSessionId("0");
						sentMessage.setUserId(uid);
						sentMessage.setRobotId(robotId);
						sentMessage.setTenantId(tenantId);
						sentMessage.setMsgType(MsgTypeEnum.ROBOT.getCode());
						sentMessage.setMessageId(messageId);
						sentMessage.setTimestamp(System.currentTimeMillis());
						sentMessage.setContent("[DONE]");

						try {
							sseEmitter.send(SseEmitter.event().id(messageId).reconnectTime(1*60*1000L).data(JSONUtil.toJsonStr(sentMessage)));
						}catch (IOException e) {
							log.error("RobotController createSse error:{}",e.getMessage());
							throw new BizException(ResultCodeEnum.IM_SESSION_CREATE_ERROR);
						}finally {
							sseEmitter.complete();
						}

					}

					@Override
					public void onError(Exception err) {
						log.error("RobotController createSse error:{}",err.getMessage());
						try {
							sseEmitter.send(SseEmitter.event().id(messageId).reconnectTime(1*60*1000L).data(err.getMessage()));
						} catch (IOException e) {
							throw new BizException(ResultCodeEnum.IM_SESSION_CREATE_ERROR);
						}finally {
							sseEmitter.complete();
						}

					}
				});
				robotService.robotQuery(queryContext);
			}catch (Exception e){
				log.error("RobotController createSse error:{}",e.getMessage());
				try {
					sseEmitter.send(SseEmitter.event().id("0").reconnectTime(1*60*1000L).data(e.getMessage()));
				} catch (IOException ex) {
					throw new BizException(ResultCodeEnum.IM_SESSION_CREATE_ERROR);
				}finally {
					sseEmitter.complete();
				}
 			}

		});

		return sseEmitter;

	}

}
